#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
客户管理组件
"""

from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QTableWidget, 
                            QTableWidgetItem, QPushButton, QLineEdit, QLabel, 
                            QMessageBox, QDialog, QFormLayout, QDialogButtonBox,
                            QHeaderView, QFrame, QDoubleSpinBox, QFileDialog,
                            QProgressDialog)
from PyQt6.QtCore import Qt, pyqtSignal, QThread, pyqtSlot
from PyQt6.QtGui import QFont
import pandas as pd
import os


class CustomerManagementWidget(QWidget):
    """客户管理组件"""
    
    # 信号定义
    customer_updated = pyqtSignal()  # 客户数据更新信号
    
    def __init__(self, websocket_client=None):
        super().__init__()
        # 使用单例WebSocket管理器
        from ..websocket_client import get_websocket_manager
        self.websocket_client = websocket_client or get_websocket_manager()
        self.customers_data = []  # 存储客户数据
        
        self.init_ui()
        
        # 连接WebSocket信号（如果可用）
        if self.websocket_client:
            self.websocket_client.connected.connect(self._on_websocket_connected)
            # 如果已经连接，立即请求数据
            if self.websocket_client.is_connected():
                self._request_customers()
        else:
            print("📋 没有WebSocket客户端")
    
    def init_ui(self):
        """初始化用户界面"""
        layout = QVBoxLayout(self)
        layout.setSpacing(10)
        layout.setContentsMargins(10, 10, 10, 10)
        
        # 创建标题
        title_label = QLabel("客户管理")
        title_label.setObjectName("section_title")
        title_label.setFont(QFont("Microsoft YaHei", 14, QFont.Weight.Bold))
        layout.addWidget(title_label)
        
        # 创建工具栏
        toolbar_frame = QFrame()
        toolbar_frame.setObjectName("toolbar_frame")
        toolbar_layout = QHBoxLayout(toolbar_frame)
        toolbar_layout.setSpacing(10)
        
        # 添加客户按钮
        self.add_customer_btn = QPushButton("添加客户")
        self.add_customer_btn.setObjectName("primary_button")
        self.add_customer_btn.clicked.connect(self._show_add_customer_dialog)
        toolbar_layout.addWidget(self.add_customer_btn)
        
        # Excel导入按钮
        self.import_excel_btn = QPushButton("Excel导入")
        self.import_excel_btn.setObjectName("secondary_button")
        self.import_excel_btn.clicked.connect(self._import_from_excel)
        toolbar_layout.addWidget(self.import_excel_btn)
        
        # 移除手动刷新按钮，改为自动刷新
        
        toolbar_layout.addStretch()
        layout.addWidget(toolbar_frame)
        
        # 创建客户表格
        self.setup_table()
        layout.addWidget(self.table)
    
    def setup_table(self):
        """设置客户表格"""
        self.table = QTableWidget()
        self.table.setObjectName("customer_table")
        
        # 设置列
        headers = ["客户名称", "单价", "操作"]
        self.table.setColumnCount(len(headers))
        self.table.setHorizontalHeaderLabels(headers)
        
        # 设置表格属性
        self.table.setAlternatingRowColors(True)
        self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
        self.table.setSelectionMode(QTableWidget.SelectionMode.SingleSelection)
        self.table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
        
        # 设置列宽
        header = self.table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)  # 客户名称列自适应
        header.setSectionResizeMode(1, QHeaderView.ResizeMode.ResizeToContents)  # 单价列自适应内容
        header.setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)  # 操作列自适应内容
        
        # 设置行高
        self.table.verticalHeader().setDefaultSectionSize(40)
    
    def update_customers_data(self, customers_data: list):
        """更新客户数据"""
        self.customers_data = customers_data
        self._update_table_from_data()
    
    def _update_table_from_data(self):
        """从数据更新表格"""
        self.table.setRowCount(len(self.customers_data))
        
        for row, customer_data in enumerate(self.customers_data):
            # 客户名称列
            name_item = QTableWidgetItem(customer_data.get('name', ''))
            self.table.setItem(row, 0, name_item)
            
            # 单价列
            price_value = customer_data.get('price', 0)
            price_text = f"{price_value:.4f}" if isinstance(price_value, (int, float)) else "0.0000"
            price_item = QTableWidgetItem(price_text)
            self.table.setItem(row, 1, price_item)
            
            # 操作列
            self._add_action_buttons(row, customer_data)
    
    def _add_action_buttons(self, row: int, customer_data: dict):
        """添加操作按钮"""
        button_widget = QWidget()
        button_layout = QHBoxLayout(button_widget)
        button_layout.setContentsMargins(5, 5, 5, 5)
        button_layout.setSpacing(5)
        
        # 编辑按钮
        edit_btn = QPushButton("编辑")
        edit_btn.setObjectName("edit_button")
        edit_btn.clicked.connect(lambda: self._show_edit_customer_dialog(row, customer_data))
        button_layout.addWidget(edit_btn)
        
        # 删除按钮
        delete_btn = QPushButton("删除")
        delete_btn.setObjectName("delete_button")
        delete_btn.clicked.connect(lambda: self._delete_customer(row, customer_data))
        button_layout.addWidget(delete_btn)
        
        self.table.setCellWidget(row, 2, button_widget)
    
    def _show_add_customer_dialog(self):
        """显示添加客户对话框"""
        dialog = CustomerDialog(self)
        if dialog.exec() == QDialog.DialogCode.Accepted:
            customer_data = dialog.get_customer_data()
            self._add_customer(customer_data)
    
    def _show_edit_customer_dialog(self, row: int, customer_data: dict):
        """显示编辑客户对话框"""
        dialog = CustomerDialog(self, customer_data)
        if dialog.exec() == QDialog.DialogCode.Accepted:
            new_customer_data = dialog.get_customer_data()
            self._update_customer(row, new_customer_data)
    
    def _add_customer(self, customer_data: dict):
        """添加客户"""
        # 发送到服务端
        if self.websocket_client:
            self.websocket_client.send_message({
                'type': 'create_customer',
                'data': customer_data
            })
            print(f"📤 发送创建客户请求: {customer_data['name']}")
        else:
            print("📋 没有WebSocket客户端")
    
    def _update_customer(self, row: int, customer_data: dict):
        """更新客户"""
        # 发送到服务端
        if self.websocket_client:
            customer_data['id'] = self.customers_data[row].get('id')
            self.websocket_client.send_message({
                'type': 'update_customer',
                'data': customer_data
            })
            print(f"📤 发送更新客户请求: {customer_data['name']}")
        else:
            print("📋 没有WebSocket客户端")
    
    def _delete_customer(self, row: int, customer_data: dict):
        """删除客户"""
        # 确认删除
        reply = QMessageBox.question(
            self, 
            "确认删除", 
            f"确定要删除客户 '{customer_data.get('name', '')}' 吗？",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
            QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            # 发送到服务端
            if self.websocket_client:
                self.websocket_client.send_message({
                    'type': 'delete_customer',
                    'customer_id': customer_data.get('id')
                })
                print(f"📤 发送删除客户请求: {customer_data.get('name')}")
            else:
                print("📋 没有WebSocket客户端")
    
    def _on_websocket_connected(self):
        """WebSocket连接时自动请求客户数据"""
        self._request_customers()
    
    def _request_customers(self):
        """请求客户数据"""
        if self.websocket_client and self.websocket_client.is_connected():
            self.websocket_client.send_message({'type': 'get_customers'})
            print("📋 请求客户数据...")
        else:
            print("📋 没有WebSocket客户端")
    
    def _refresh_customers(self):
        """刷新客户数据（保留用于兼容性）"""
        self._request_customers()
    
    def _import_from_excel(self):
        """从Excel导入客户"""
        # 显示导入对话框
        dialog = ExcelImportDialog(self)
        if dialog.exec() == QDialog.DialogCode.Accepted:
            file_path = dialog.get_file_path()
            if file_path and os.path.exists(file_path):
                self._start_excel_import(file_path)
            else:
                QMessageBox.warning(self, "文件错误", "请选择有效的Excel文件")
    
    def _start_excel_import(self, file_path: str):
        """开始Excel导入"""
        # 创建进度对话框
        self.progress_dialog = QProgressDialog("正在导入Excel文件...", "取消", 0, 100, self)
        self.progress_dialog.setWindowTitle("Excel导入")
        self.progress_dialog.setModal(True)
        self.progress_dialog.show()
        
        # 创建导入线程
        self.import_thread = ExcelImportThread(file_path)
        self.import_thread.progress_updated.connect(self._on_import_progress)
        self.import_thread.import_finished.connect(self._on_import_finished)
        self.import_thread.import_error.connect(self._on_import_error)
        
        # 连接取消信号
        self.progress_dialog.canceled.connect(self._cancel_import)
        
        # 启动线程
        self.import_thread.start()
    
    @pyqtSlot(int)
    def _on_import_progress(self, progress: int):
        """导入进度更新"""
        if hasattr(self, 'progress_dialog') and self.progress_dialog:
            self.progress_dialog.setValue(progress)
    
    @pyqtSlot(list, str)
    def _on_import_finished(self, customers_data: list, message: str):
        """导入完成"""
        if hasattr(self, 'progress_dialog') and self.progress_dialog:
            self.progress_dialog.close()
        
        if customers_data:
            # 批量发送到服务端
            self._batch_import_customers(customers_data)
            QMessageBox.information(self, "导入成功", message)
        else:
            QMessageBox.warning(self, "导入失败", "没有找到有效的客户数据")
    
    @pyqtSlot(str)
    def _on_import_error(self, error_msg: str):
        """导入错误"""
        if hasattr(self, 'progress_dialog') and self.progress_dialog:
            self.progress_dialog.close()
        
        QMessageBox.critical(self, "导入错误", error_msg)
    
    def _cancel_import(self):
        """取消导入"""
        if hasattr(self, 'import_thread') and self.import_thread:
            self.import_thread.terminate()
            self.import_thread.wait()
        
        if hasattr(self, 'progress_dialog') and self.progress_dialog:
            self.progress_dialog.close()
    
    def _batch_import_customers(self, customers_data: list):
        """批量导入客户"""
        if not self.websocket_client or not self.websocket_client.is_connected():
            QMessageBox.warning(self, "连接错误", "WebSocket未连接，无法导入客户")
            return
        
        # 过滤掉已存在的客户
        existing_names = {customer.get('name', '') for customer in self.customers_data}
        new_customers = []
        skipped_count = 0
        
        for customer_data in customers_data:
            customer_name = customer_data.get('name', '')
            if customer_name in existing_names:
                print(f"⏭️ 客户 '{customer_name}' 已存在，跳过")
                skipped_count += 1
            else:
                new_customers.append(customer_data)
        
        if not new_customers:
            QMessageBox.information(self, "导入完成", f"所有客户都已存在，共跳过 {skipped_count} 个客户")
            return
        
        # 先更新本地表格
        for customer_data in new_customers:
            self.customers_data.append(customer_data)
        
        # 更新表格显示
        self._update_table_from_data()
        
        # 批量发送到服务端
        self.websocket_client.send_message({
            'type': 'batch_create_customers',
            'data': new_customers
        })
        
        print(f"📤 批量导入完成，新增 {len(new_customers)} 个客户，跳过 {skipped_count} 个已存在客户")
    
    def handle_websocket_message(self, message: dict):
        """处理WebSocket消息"""
        msg_type = message.get('type')
        
        if msg_type == 'customers_received':
            customers = message.get('customers', [])
            self.update_customers_data(customers)
            print(f"📋 收到客户列表: {len(customers)} 个客户")
        
        elif msg_type == 'customer_created':
            customer = message.get('customer')
            if customer:
                customer_name = customer.get('name', '')
                
                # 检查是否已存在相同名称的客户
                existing_customer = None
                for existing in self.customers_data:
                    if existing.get('name') == customer_name:
                        existing_customer = existing
                        break
                
                if existing_customer:
                    # 如果已存在，更新现有客户信息
                    existing_customer.update(customer)
                    print(f"🔄 客户已存在，更新信息: {customer_name}")
                else:
                    # 如果不存在，添加新客户
                    self.customers_data.append(customer)
                    print(f"✅ 客户创建成功: {customer_name}")
                
                self._update_table_from_data()
                self.customer_updated.emit()
        
        elif msg_type == 'customers_batch_created':
            customers = message.get('customers', [])
            if customers:
                # 批量添加新客户到本地数据
                for customer in customers:
                    customer_name = customer.get('name', '')
                    
                    # 检查是否已存在相同名称的客户
                    existing_customer = None
                    for existing in self.customers_data:
                        if existing.get('name') == customer_name:
                            existing_customer = existing
                            break
                    
                    if not existing_customer:
                        # 如果不存在，添加新客户
                        self.customers_data.append(customer)
                        print(f"✅ 批量客户创建成功: {customer_name}")
                
                self._update_table_from_data()
                self.customer_updated.emit()
                print(f"✅ 批量客户创建完成: {len(customers)} 个客户")
        
        elif msg_type == 'customer_updated':
            customer = message.get('customer')
            if customer:
                # 更新现有客户
                for i, existing_customer in enumerate(self.customers_data):
                    if existing_customer.get('id') == customer.get('id'):
                        # 比较现有数据和新数据是否完全一致
                        if self._is_customer_data_identical(existing_customer, customer):
                            print(f"⏭️ 客户数据完全一致，跳过更新: {customer['name']}")
                            return
                        
                        print(f"🔄 客户数据有变化，开始更新: {customer['name']}")
                        self.customers_data[i] = customer
                        break
                self._update_table_from_data()
                self.customer_updated.emit()
                print(f"✅ 客户更新成功: {customer['name']}")
        
        elif msg_type == 'customer_deleted':
            customer_id = message.get('customer_id')
            if customer_id:
                # 删除客户
                self.customers_data = [c for c in self.customers_data if c.get('id') != customer_id]
                self._update_table_from_data()
                self.customer_updated.emit()
                print(f"✅ 客户删除成功: ID {customer_id}")
        
        # 对于其他客户相关操作，自动刷新数据
        elif msg_type in ['customer_created', 'customer_updated', 'customer_deleted']:
            # 延迟一点时间后自动刷新，确保服务端数据已更新客户数据已更新
            from PyQt6.QtCore import QTimer
            QTimer.singleShot(100, self._request_customers)
    
    def _is_customer_data_identical(self, existing_data: dict, new_data: dict) -> bool:
        """比较两个客户数据是否完全一致"""
        try:
            # 需要比较的关键字段
            key_fields = ['id', 'name', 'price', 'note']
            
            for field in key_fields:
                existing_value = existing_data.get(field, '')
                new_value = new_data.get(field, '')
                
                # 处理None值
                if existing_value is None:
                    existing_value = ''
                if new_value is None:
                    new_value = ''
                
                # 转换为字符串进行比较
                existing_str = str(existing_value).strip()
                new_str = str(new_value).strip()
                
                if existing_str != new_str:
                    print(f"🔍 客户字段 '{field}' 不一致: '{existing_str}' vs '{new_str}'")
                    return False
            
            print(f"✅ 客户数据完全一致")
            return True
            
        except Exception as e:
            print(f"❌ 比较客户数据时出错: {e}")
            return False


class CustomerDialog(QDialog):
    """客户对话框"""
    
    def __init__(self, parent=None, customer_data=None):
        super().__init__(parent)
        self.customer_data = customer_data or {}
        self.setWindowTitle("编辑客户" if customer_data else "添加客户")
        self.setModal(True)
        self.setFixedSize(400, 200)
        self.init_ui()
    
    def init_ui(self):
        """初始化界面"""
        layout = QVBoxLayout(self)
        layout.setSpacing(15)
        layout.setContentsMargins(20, 20, 20, 20)
        
        # 创建表单
        form_layout = QFormLayout()
        form_layout.setSpacing(10)
        
        # 客户名称输入框
        self.name_input = QLineEdit()
        self.name_input.setPlaceholderText("请输入客户名称")
        if self.customer_data:
            self.name_input.setText(self.customer_data.get('name', ''))
        form_layout.addRow("客户名称:", self.name_input)
        
        # 单价输入框
        self.price_input = QDoubleSpinBox()
        self.price_input.setDecimals(4)  # 设置最多4位小数
        self.price_input.setRange(0.0, 999999.9999)  # 设置范围
        self.price_input.setSuffix(" 元")  # 添加单位后缀
        self.price_input.setButtonSymbols(QDoubleSpinBox.ButtonSymbols.UpDownArrows)
        if self.customer_data:
            self.price_input.setValue(self.customer_data.get('price', 0.0))
        form_layout.addRow("单价:", self.price_input)
        
        layout.addLayout(form_layout)
        
        # 按钮
        button_box = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
        )
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        layout.addWidget(button_box)
    
    def get_customer_data(self):
        """获取客户数据"""
        return {
            'name': self.name_input.text().strip(),
            'price': self.price_input.value()  # QDoubleSpinBox使用value()方法
        }
    
    def accept(self):
        """确认按钮处理"""
        name = self.name_input.text().strip()
        if not name:
            QMessageBox.warning(self, "输入错误", "客户名称不能为空！")
            return
        
        # QDoubleSpinBox会自动验证数字，不需要手动检查
        super().accept()


class ExcelImportThread(QThread):
    """Excel导入线程"""
    
    # 信号定义
    progress_updated = pyqtSignal(int)  # 进度更新信号
    import_finished = pyqtSignal(list, str)  # 导入完成信号 (customers_data, message)
    import_error = pyqtSignal(str)  # 导入错误信号
    
    def __init__(self, file_path: str):
        super().__init__()
        self.file_path = file_path
    
    def run(self):
        """运行导入线程"""
        try:
            # 读取Excel文件
            self.progress_updated.emit(10)
            
            # 支持多种Excel格式
            if self.file_path.endswith('.xlsx'):
                df = pd.read_excel(self.file_path, engine='openpyxl')
            elif self.file_path.endswith('.xls'):
                df = pd.read_excel(self.file_path, engine='xlrd')
            else:
                raise ValueError("不支持的文件格式，请选择 .xlsx 或 .xls 文件")
            
            self.progress_updated.emit(30)
            
            self.progress_updated.emit(50)
            
            # 处理数据 - 不检查列标题，直接按列位置处理
            customers_data = []
            seen_names = set()  # 用于去重
            total_rows = len(df)
            
            for index, row in df.iterrows():
                try:
                    # 获取第一列作为客户名称
                    name = str(row.iloc[0]).strip()
                    if not name or name == 'nan':
                        continue
                    
                    # 检查是否已存在相同名称的客户（Excel内部去重）
                    if name in seen_names:
                        print(f"第 {index + 1} 行客户名称 '{name}' 在Excel中重复，跳过")
                        continue
                    
                    # 获取第二列作为单价，检查是否为数字
                    if len(row) < 2:
                        print(f"第 {index + 1} 行数据不足，跳过")
                        continue
                    
                    price_value = row.iloc[1]
                    
                    # 检查第二列是否为数字
                    if pd.isna(price_value):
                        print(f"第 {index + 1} 行单价为空，跳过")
                        continue
                    
                    try:
                        price = float(price_value)
                    except (ValueError, TypeError):
                        print(f"第 {index + 1} 行单价不是数字格式: {price_value}，跳过")
                        continue
                    
                    # 创建客户数据
                    customer_data = {
                        'name': name,
                        'price': price
                    }
                    
                    customers_data.append(customer_data)
                    seen_names.add(name)  # 记录已处理的客户名称
                    
                    # 更新进度
                    progress = 50 + int((index + 1) / total_rows * 40)
                    self.progress_updated.emit(progress)
                    
                except Exception as e:
                    print(f"处理第 {index + 1} 行数据时出错: {e}")
                    continue
            
            self.progress_updated.emit(100)
            
            # 发送完成信号
            message = f"成功导入 {len(customers_data)} 个客户"
            self.import_finished.emit(customers_data, message)
            
        except Exception as e:
            error_msg = f"导入Excel文件失败: {str(e)}"
            self.import_error.emit(error_msg)


class ExcelImportDialog(QDialog):
    """Excel导入对话框"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Excel导入客户")
        self.setModal(True)
        self.setFixedSize(500, 400)
        self.file_path = ""
        self.init_ui()
    
    def init_ui(self):
        """初始化界面"""
        layout = QVBoxLayout(self)
        layout.setSpacing(15)
        layout.setContentsMargins(20, 20, 20, 20)
        
        # 说明文本
        info_label = QLabel("请选择包含客户信息的Excel文件")
        info_label.setFont(QFont("Microsoft YaHei", 10))
        layout.addWidget(info_label)
        
        # 文件选择区域
        file_layout = QHBoxLayout()
        
        self.file_path_input = QLineEdit()
        self.file_path_input.setPlaceholderText("请选择Excel文件...")
        self.file_path_input.setReadOnly(True)
        file_layout.addWidget(self.file_path_input)
        
        self.browse_btn = QPushButton("浏览")
        self.browse_btn.clicked.connect(self._browse_file)
        file_layout.addWidget(self.browse_btn)
        
        layout.addLayout(file_layout)
        
        # Excel格式说明
        format_label = QLabel("Excel文件格式要求：")
        format_label.setFont(QFont("Microsoft YaHei", 9, QFont.Weight.Bold))
        layout.addWidget(format_label)
        
        format_text = QLabel("""
• 文件格式：.xlsx 或 .xls
• 第一列：客户名称（文本格式，不能为空）
• 第二列：单价（数字格式，支持小数）
• 第二列不是数字的行将被自动跳过
• 空行将被自动跳过
• 不需要特定的列标题
        """)
        format_text.setFont(QFont("Microsoft YaHei", 9))
        format_text.setStyleSheet("color: #666; background-color: #f5f5f5; padding: 10px; border-radius: 5px;")
        layout.addWidget(format_text)
        
        # 按钮
        self.button_box = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
        )
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)
        layout.addWidget(self.button_box)
        
        # 初始状态禁用OK按钮
        self.button_box.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
        self.file_path_input.textChanged.connect(self._on_file_path_changed)
    
    def _browse_file(self):
        """浏览文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "选择Excel文件",
            "",
            "Excel文件 (*.xlsx *.xls);;所有文件 (*)"
        )
        
        if file_path:
            self.file_path = file_path
            self.file_path_input.setText(file_path)
    
    def _on_file_path_changed(self):
        """文件路径变化处理"""
        has_file = bool(self.file_path_input.text().strip())
        self.button_box.button(QDialogButtonBox.StandardButton.Ok).setEnabled(has_file)
    
    def get_file_path(self):
        """获取文件路径"""
        return self.file_path
